package com.comprosoft.telnet.server;

import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.comprosoft.telnet.command.AllCommands;
import com.comprosoft.telnet.command.Command;
import com.comprosoft.telnet.command.SystemCommandHandler;
import com.comprosoft.telnet.io.IOHandler;
import com.comprosoft.telnet.io.TextColor;

/**
 * Client Worker handling request of a client.<br>
 * <br>
 * <b>Created by: </b>Bryan McClain, Comprosoft 2017<br>
 * <b>Original code: </b> A.Khettar
 */
public class ClientWorker implements Runnable {

    private Socket socket;
    private IOHandler io;
    private Logger logger = Logger.getLogger(ClientWorker.class.getName());
    private int maxWaitTime;
    volatile long startTime = 0;

    /**
     * Create a new Telnet Server client worker
     *
     * @param socket  The socket running the server
     * @param homeDir The home directory for the server
     * @throws IOException
     */
    public ClientWorker(final Socket socket, String homeDir) throws IOException {
        this.socket = socket;
        this.io = new IOHandler(socket);
        //每隔10秒钟没操作则将当前远程连接关闭
        this.maxWaitTime = 10000;
    }


    /*
     * Execute the server code for this client
     */
    @Override
    public void run() {
        try {
            showWelcomeScreen();
            Thread thread = Thread.currentThread();
            boolean cancel = false;
            startTime = System.currentTimeMillis();
            new Thread(new Runnable(){

                @Override
                public void run() {
                    //当连接达到最大时间，则退出

                    while ((System.currentTimeMillis() - startTime) < maxWaitTime){
                        try {
                            Thread.sleep(1000);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    thread.interrupt();

                }
            }).start();
            boolean usernameFilled = false;
            boolean passwordFilled = false;
            while (!cancel&&!thread.isInterrupted()) {
                String command = null;
                if (!usernameFilled) {
                    io.SetTextColor(TextColor.YELLOW);
                    command = io.readLine("username: ");
                    command = "username " + command;
                } else if (!passwordFilled) {
                    io.SetTextColor(TextColor.YELLOW);
                    command = io.readLine("password: ");
                    command = "password " + command;

                } else {
                    io.SetTextColor(TextColor.WHITE);
                    command = io.readLine("-> ");
                }
                command = command.trim();
                command = command.replaceAll("\\P{Print}", "");

                if (command == null) {
                    io.WriteLine("Null!");
                    continue;
                }

                if (command.length() == 0) {
                    continue;
                }


                //handle the command
                String tokens[] = Command.tokenize(command);
                Command cmd = AllCommands.getCommand(tokens[0], io);

                switch (cmd.handle(tokens)) {
                    case COMMAND_EXIT:
                        cancel = true;
                        break;

                    case COMMAND_RESPLASH:
                        io.ClearScreen();
                        showWelcomeScreen();
                        break;
                    case COMMAND_FILLED_USERNAME:
                        usernameFilled = true;
                        io.WriteLine("");
                        io.WriteLine("");
                        break;
                    case COMMAND_FILLED_PASSWORD:
                        passwordFilled = true;
                        io.WriteLine("");
                        io.WriteLine("");
                        break;
                    default:
                        break;

                }
                //每次执行命令都刷新当前时间
                startTime = System.currentTimeMillis();
            }

        } catch (IOException e) {
            io.SetTextColor(TextColor.RED);
            io.WriteLine(e.getMessage());
            logger.log(Level.SEVERE, e.getMessage(), e);
        } finally {
            try {
                io.WriteLine("\ntelnet link has been closed");
                io.Flush();
                io.destroy();
                socket.close();
            } catch (IOException e) {
                logger.log(Level.SEVERE, "Failed to close the socket", e);
            }
        }
    }


    /**
     * Builds welcome screen.
     *
     * @return
     */
    private void showWelcomeScreen() {

        io.SetTextColor(TextColor.WHITE);
        io.WriteLine("");
        io.WriteLine("======================================================");
        io.WriteLine("");
        io.WriteLine("   Welcome to Comprosoft Telnet Server: Version 1.0   ");
        io.WriteLine("");
        io.WriteLine("======================================================");

        io.WriteLine("");
        io.WriteLine("");

        io.SetTextColor(TextColor.CYAN);
        io.Write("Type ");
        io.SetTextColor(TextColor.MAGENTA);
        io.Write("\"List\"");
        io.SetTextColor(TextColor.CYAN);
        io.WriteLine(" to show all available commands.");

        io.WriteLine("");
        io.WriteLine("");
    }

}
